home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / video / seqgrab / seqgrab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  21.3 KB  |  907 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18.  
  19. /*
  20.  *  seqgrab.c - sequential frame accurate grabbing on Galileo w/hw trigger
  21.  * 
  22.  *  Grabs a sequence of frames between start and end timecodes.  This
  23.  *  works on a very specific configuration of equipment, namely a 
  24.  *  system with a Galileo video board, a frame accurate device and a
  25.  *  VLAN controller.
  26.  * 
  27.  *  Note: this app currently does not support framedrop timecode.
  28.  *
  29.  *  John Magdziarz  01.31.94 
  30.  *               
  31.  */
  32.  
  33. #include <unistd.h>
  34. #include <string.h>
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include <signal.h>
  38. #include <malloc.h>
  39. #include <getopt.h>
  40. #include <sys/types.h>
  41. #include <sys/stat.h>
  42. #include <fcntl.h>
  43. #include <gl/gl.h>
  44. #include <gl/image.h>
  45. #include <vl/vl.h>
  46. #include "vlan.h"
  47. #include "cv.h"
  48.  
  49. char *deviceName;
  50. char *_progName;
  51.  
  52. #ifndef MAXNAMLEN
  53. #define MAXNAMLEN 1024
  54. #endif
  55.  
  56. #define CMDLEN 20
  57. #define MAXFGRAB 3
  58. #define MINENDPOINT 5
  59.  
  60. int icount = 0;
  61. char iname[MAXNAMLEN];
  62. char outfilename[MAXNAMLEN - 5] = "";
  63. int captCount = 0;
  64. int writeFrame = 1;
  65. int forcedWriteFrame = 0;
  66. int rawMode = 0;
  67. int displayFrame = 0;
  68. int decodeTC = 0;
  69. VLServer svr;
  70. VLBuffer buffer;
  71. VLPath path;
  72. VLNode src, drn;
  73. VLTransferDescriptor xferDesc;
  74. int xsize = 0;
  75. int ysize = 0;
  76. int xsetsize = 0;
  77. int ysetsize = 0;
  78. int frameSize;
  79. char *strSC = "SC ";
  80. char *strSI = "SI ";
  81. char *strSO = "SO ";
  82. char *strPR = "PR ";
  83. char tcSI[CMDLEN], cmdSI[CMDLEN];
  84. char tcSO[CMDLEN], cmdSO[CMDLEN];
  85. char tcSC[CMDLEN], cmdSC[CMDLEN];
  86. char tcPR[CMDLEN], cmdPR[CMDLEN];
  87. int fcntSI;
  88. int fcntSO;
  89. char tcTMP[CMDLEN];
  90. int lastCoinFr;
  91. char cmd[256], buf[256], *cmdName, *response;
  92. Boolean inpoint = FALSE;
  93. Boolean outpoint = FALSE;
  94. int totalFrames = 0;
  95. int totalTriggers = 0;
  96. int remFrames = 0;
  97. int offset = -1;
  98. ulong tc, ub, crc;
  99.  
  100. VLDevList devlist;
  101. VLControlValue val;
  102. int c;
  103. int vin;
  104. int devicenum = -1;
  105. int forced_node = 0;
  106. int zoom_num = 1;
  107. int zoom_denom = 1;
  108. int ext_trig = 1;  /* always hang out for external trigger */
  109. int node = 0;
  110. int verbose = 0;
  111. int deinterlace = 0;
  112.  
  113. void docleanup();
  114. void ProcessEvent(VLServer, VLEvent *, void *);
  115. void usage(void);
  116. char *get_packing(void);
  117. int reportPerf(int);
  118.  
  119. #define GRABFILE    "out"
  120.  
  121. #define USAGE \
  122. "%s: -i <start SMPTE tc> -o <end SMPTE tc> [-f <filename>]\n\
  123. \t\t[-w] [-d] [-s w h] [-n <device>] [-v <videonode> ]\n\
  124. \t\t[-c <num>] [-r] [-t] [-z n/d] [-O <frames>] [-D] [-h]\n\
  125. \t-i\tstarting <SMPTE timecode> to grab frames\n\
  126. \t-o\tending <SMPTE timecode> to grab frames\n\
  127. \t-f\toutput filename\n\
  128. \t-w\tdon't write frame to disk\n\
  129. \t-d\tdisplay captured frame\n\
  130. \t-s w h\tframe dimensions (must be last option if specified)\n\
  131. \t-c num\tnumber of frames to capture\n\
  132. \t-n device\tdevice number to use\n\
  133. \t-r\traw mode output (no YUV->RGB or de-interlace)\n\
  134. \t-v\tvideo source node number\n\
  135. \t-z\tzoom the image by n/d\n\
  136. \t-O\toffset # frames from starting timecode (default = -1)\n\
  137. \t-p\tpreroll time <SMPTE timecode> (default 5 sec.)\n\
  138. \t-V\tverbose\n\
  139. \t-D\tde-interlace captured frame (repeat even field)\n\
  140. \t-h\tthis help message\n"
  141.  
  142. void 
  143. usage(void)
  144. {
  145.     fprintf(stderr, USAGE, _progName);
  146. }
  147.  
  148.  
  149. /* Dump data to image file */
  150. void
  151. DumpImage(char *data, int xinputsize, int xoutputsize, int yinputsize, 
  152.           int youtputsize, int transferSize)
  153. {
  154.     IMAGE *image;
  155.     int fd, ret;
  156.     unsigned short rbuf[1024];
  157.     unsigned short gbuf[1024];
  158.     unsigned short bbuf[1024];
  159.     char *outdata, *temp;
  160.     int fileSize;
  161.     int x, y, z;
  162.     int yinc;
  163.  
  164.     sprintf(iname,"%s-%05d", outfilename, icount++);
  165.     if (rawMode) 
  166.     {
  167.         strcat(iname, ".");
  168.         strcat(iname, get_packing());
  169.         fd = open(iname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
  170.         if (fd < 0) 
  171.         {
  172.             perror(iname);
  173.             exit(1);
  174.         }
  175.         /* Do clipping if requested */
  176.         if ((xinputsize != xoutputsize)||(yinputsize != youtputsize))
  177.         {
  178.             fileSize = youtputsize * xoutputsize * 2;
  179.             outdata = (char *)malloc(fileSize*sizeof(char));
  180.             if (!outdata)
  181.             {
  182.                 fprintf(stderr,"DumpImage: can't malloc enough memory\n");
  183.                 exit(1);
  184.             }
  185.             temp = outdata;
  186.             for (y = 0; y < youtputsize; y++)
  187.             {
  188.                 for (x = 0; x < xoutputsize; x++)
  189.                 {
  190.                    *(temp++) = *(data++);
  191.                    *(temp++) = *(data++);
  192.                 }
  193.                 /* Clip data to user requested frame size */
  194.                 for (x = xoutputsize; x < xinputsize; x++)
  195.                 {
  196.                    data++;
  197.                    data++;
  198.                 }
  199.             }           
  200.             ret = write(fd, outdata, fileSize);
  201.             free(outdata);
  202.         }           
  203.         else 
  204.         {
  205.             fileSize = transferSize;
  206.             ret = write(fd, data, fileSize);
  207.         }
  208.         if (ret < fileSize) 
  209.         {
  210.             perror(iname);
  211.             exit(1);
  212.         }
  213.         close(fd);
  214.     } else 
  215.     {
  216.         if (writeFrame) 
  217.         {
  218.             strcat(iname, ".rgb");
  219.             image = iopen(iname, "w", RLE(1), 3, xoutputsize, youtputsize, 3);
  220.         }
  221.     
  222.         /* Write RGB data to buffers */
  223.         /* double even fields to deinterlace image */
  224.         if (deinterlace)
  225.           yinc = 2;
  226.         else 
  227.           yinc = 1; 
  228.         for (y=0;y<youtputsize;y+=yinc) 
  229.         {
  230.         /* One pixel at a time along scan line */
  231.             for(x=0;x<xoutputsize;x++) 
  232.             {
  233.                 data++;
  234.                 bbuf[x] = *(data++);
  235.                 gbuf[x] = *(data++);
  236.                 rbuf[x] = *(data++);
  237.             }
  238.             /* Clip data to user requested frame size */
  239.             for (x=xoutputsize; x<xinputsize; x++)
  240.             {
  241.                data++;
  242.                data++;
  243.                data++;
  244.                data++;
  245.             }
  246.             if (writeFrame) 
  247.             {
  248.                 /* Write RGB buffers to disk */
  249.                 putrow(image, rbuf, youtputsize - y - 1, 0);
  250.                 putrow(image, gbuf, youtputsize - y - 1, 1);
  251.                 putrow(image, bbuf, youtputsize - y - 1, 2);
  252.                 putrow(image, rbuf, youtputsize - y - 2, 0);
  253.                 putrow(image, gbuf, youtputsize - y - 2, 1);
  254.                 putrow(image, bbuf, youtputsize - y - 2, 2);
  255.             }
  256.         }
  257.         if (writeFrame)
  258.             iclose(image);
  259.     }
  260. }
  261.  
  262.  
  263.  
  264. char *ToUpper(char *str) {
  265.     char *c;
  266.     if ((c = str) != NULL)
  267.         for (; *c != '\0'; c++)
  268.             if (*c >= 'a' && *c <= 'z') *c += 'A' - 'a';
  269.     return str;
  270. }
  271.  
  272. void
  273. setVCmdStr(char *cmd, char *cmdstr, char *tcstr, char *tc)
  274. {
  275.   strncpy(tcstr, tc, CMDLEN);
  276.   strncpy(cmd, cmdstr, CMDLEN);   
  277.   strncat(cmd, tcstr, CMDLEN);   
  278. }
  279.  
  280. void
  281. parseOptions(int argc, char **argv)
  282. {
  283.     while ((c = getopt(argc, argv, "f:wdn:c:rhs:v:z:ti:o:O:p:DVT")) != EOF) 
  284.     {
  285.     switch (c) 
  286.     {
  287.         case 'f':
  288.         sprintf(outfilename,"%s",optarg);
  289.         break;
  290.         
  291.         case 'c':
  292.         captCount = atoi(optarg);
  293.         if (captCount > MAXFGRAB) {
  294.           printf("capture count set to maximum of %d", MAXFGRAB);
  295.           captCount = MAXFGRAB;
  296.         }
  297.         break;
  298.         
  299.         case 'w':
  300.         writeFrame = 0;
  301.         break;
  302.         
  303.         case 'd':
  304.         displayFrame = 1;
  305.         break;
  306.         
  307.         case 'V':
  308.         verbose = 1;
  309.         break;
  310.  
  311.         case 'T':
  312.         decodeTC = 1;
  313.         break;
  314.         
  315.         case 'D':
  316.         deinterlace = 1;
  317.         break;
  318.         
  319.         case 's':
  320.         xsize = atoi(optarg);
  321.         ysize = atoi(argv[optind]);
  322.         optind++;
  323.         break;
  324.         
  325.         case 'p':
  326.         setVCmdStr(cmdPR, strPR, tcPR, (char *)optarg);
  327.         break;
  328.  
  329.         case 'i':
  330.         setVCmdStr(cmdSI, strSI, tcSI, (char *)optarg);
  331.         inpoint = TRUE;
  332.         break;
  333.  
  334.         case 'o':
  335.         setVCmdStr(cmdSO, strSO, tcSO, (char *)optarg);
  336.         outpoint = TRUE;
  337.         break;
  338.  
  339.         case 'O':
  340.         offset = atoi(optarg);
  341.         break;
  342.         
  343.         case 'n':
  344.         devicenum = atoi(optarg);
  345.         break;
  346.         
  347.         case 'r':
  348.         rawMode = 1;
  349.         break;
  350.         
  351.         case 'v':
  352.         forced_node = 1;
  353.         vin = atoi(optarg);
  354.         break;
  355.                 
  356.         case 'z':
  357.         if (sscanf(optarg,"%d/%d",&zoom_num,&zoom_denom) != 2 ||
  358.         !zoom_num || !zoom_denom)
  359.         {
  360.             fprintf(stderr, "%s: ERROR zoom format is <num>/<denom>\n",
  361.             _progName);
  362.             exit(1);
  363.         }
  364.         break;
  365.         
  366.         default:
  367.         case 'h':
  368.         usage();
  369.         exit(0);
  370.         break;
  371.     }
  372.     }
  373.     
  374. }
  375.  
  376.  
  377.  
  378. void
  379. initVideo()
  380. {
  381.         /* Connect to the daemon */
  382.     if (!(svr = vlOpenVideo(""))) 
  383.     {
  384.     fprintf(stderr, "%s: couldn't open video\n", _progName);
  385.     exit(1);
  386.     }
  387.  
  388.     signal(SIGINT, docleanup);
  389.  
  390.     /* Get the list of devices that the daemon supports */
  391.     if (vlGetDeviceList(svr, &devlist) < 0) 
  392.     {
  393.     printf("%s: getting device list: %s\n",_progName,vlStrError(vlErrno));
  394.     exit(1);
  395.     }
  396.  
  397.     /* Make sure the user specified device (if any) is in the list */
  398.     if ((devicenum >= (int)devlist.numDevices) || (devicenum < -1))
  399.     {
  400.     if (devlist.numDevices == 1)
  401.         fprintf(stderr,"%s: The device number must be 0\n",_progName);
  402.     else
  403.         fprintf(stderr,"%s: The device number must be between 0 and %d\n",
  404.         _progName, devlist.numDevices-1);
  405.     exit(1);
  406.     }
  407.  
  408.     /* Set up a drain node in memory */
  409.     drn = vlGetNode(svr, VL_DRN, VL_MEM, VL_ANY);
  410.     /* Set up a source node on any source if the user did not specify one */
  411.     if (forced_node == 0)
  412.     src = vlGetNode(svr, VL_SRC, VL_VIDEO, VL_ANY);
  413.     else
  414.     /* Set up a source node on the user specified source */
  415.     src = vlGetNode(svr, VL_SRC, VL_VIDEO, vin);
  416.  
  417.     /* 
  418.      * If the user didn't specify a device create a path using the first
  419.      * device that will support it
  420.      */
  421.     if (devicenum == -1)
  422.     {
  423.     if ((path = vlCreatePath(svr, VL_ANY, src, drn)) < 0) 
  424.     {
  425.         vlPerror(_progName);
  426.         exit(1);
  427.     }
  428.     /* Get the device number and name */
  429.     devicenum = vlGetDevice(svr, path);
  430.     deviceName = devlist.devices[devicenum].name;
  431.     }
  432.     else
  433.     /* Create a path using the user specified device */
  434.     {
  435.     deviceName = devlist.devices[devicenum].name;
  436.     if ((path = vlCreatePath(svr, devicenum, src, drn)) < 0) 
  437.     {
  438.         vlPerror(_progName);
  439.         exit(1);
  440.     }
  441.     }
  442.  
  443.     /* Set up the hardware for and define the usage of the path */
  444.     if (vlSetupPaths(svr, (VLPathList)&path, 1, VL_LOCK, VL_LOCK) < 0)
  445.     {
  446.     vlPerror(_progName);
  447.     exit(1);
  448.     }
  449.  
  450.     /* 
  451.      * Specify what path-related events we want to receive. 
  452.      * In this example we want transfer complete and transfer failed
  453.      * events only.
  454.      */
  455.     vlSelectEvents(svr, path, VLTransferCompleteMask|VLTransferFailedMask);
  456.  
  457.     /* Set the zoom ratio */
  458.     val.fractVal.numerator = zoom_num;
  459.     val.fractVal.denominator = zoom_denom;
  460.     vlSetControl(svr, path, drn, VL_ZOOM, &val);
  461.  
  462.     if (decodeTC) {
  463.       val.intVal = VL_PACKING_YVYU_422_8;
  464.       val.intVal = VL_PACKING_RGB_8;
  465.       if (vlSetControl(svr, path, drn, VL_PACKING, &val))
  466.          vlPerror("not able to set packing");
  467.  
  468.       /* Set the video size, 10 lines*/
  469.       val.xyVal.x = 0;
  470.       val.xyVal.y = -9;
  471.       if (vlSetControl(svr, path, drn, VL_OFFSET, &val))
  472.         vlPerror("not able to set offset");
  473.  
  474.       vlGetControl(svr, path, drn, VL_OFFSET, &val);
  475.       printf("offset %d, %d\n", val.xyVal.x, val.xyVal.y);
  476.     
  477.       vlGetControl(svr, path, drn, VL_SIZE, &val);
  478.       printf("default xsize = %d  ysize = %d\n", val.xyVal.x, val.xyVal.y );
  479.       val.xyVal.y = 10;
  480.       val.xyVal.y = 496;
  481.       vlSetControl(svr, path, drn, VL_SIZE, &val);
  482.       vlGetControl(svr, path, drn, VL_SIZE, &val);
  483.       printf("new xsize = %d  ysize = %d\n", val.xyVal.x, val.xyVal.y );
  484.     }
  485.     else {
  486.       /* Set packing to RGB, if rawmode requested use default */
  487.       if (!rawMode)
  488.       {
  489.         val.intVal = VL_PACKING_RGB_8;
  490.     vlSetControl(svr, path, drn, VL_PACKING, &val);
  491.       }
  492.  
  493.       /* Set the video size to what the user requested */
  494.       if (!xsize)
  495.       vlGetControl(svr, path, drn, VL_SIZE, &val);
  496.       else {
  497.     val.xyVal.x = xsetsize = xsize;
  498.     val.xyVal.y = ysetsize = ysize;
  499.     vlSetControl(svr, path, drn, VL_SIZE, &val);
  500.     
  501.     /* Make sure the hardware supports this size */
  502.     vlGetControl(svr, path, drn, VL_SIZE, &val);
  503.       }
  504.     }
  505.     
  506.     if (!xsetsize)
  507.     {
  508.     xsetsize = val.xyVal.x;
  509.     ysetsize = val.xyVal.y;
  510.     }
  511.        
  512.     xsize = val.xyVal.x;
  513.     ysize = val.xyVal.y;
  514.  
  515.     frameSize = vlGetTransferSize(svr, path);
  516.  
  517.     /* Set ProcessEvent() as the callback for a transfer events */
  518.     vlAddCallback(svr, path, VLTransferCompleteMask|VLTransferFailedMask, 
  519.                      ProcessEvent, NULL);
  520.  
  521.     /* Create and register a buffer of captCount frames... */
  522.     buffer = vlCreateBuffer(svr, path, drn, captCount);
  523.     if (buffer == NULL)
  524.     {
  525.     printf("error create buffer\n");
  526.     exit(1);
  527.     }
  528.     if (vlRegisterBuffer(svr, path, drn, buffer))
  529.     {
  530.     vlPerror(_progName);
  531.     exit(1);
  532.     }
  533. }
  534.  
  535.  
  536.  
  537. void
  538. initVlanEditSeq()
  539. {
  540.     response = vlan_SendCmd("ST");  /* stop device */
  541.     response = vlan_SendCmd("EF");  /* turn echoing off */
  542.     response = vlan_SendCmd("CO");  /* turn coincidence on */
  543.     printf("Setting grab start  : %s\n", tcSI);
  544.     mc_convert(MC_NTSC_FRAME, MC_NTSC_TC, fcntSI, tcTMP);  /* convert from tc to frames */
  545.     setVCmdStr(cmdSI, strSI, tcSI, tcTMP);
  546.     response = vlan_SendCmd(cmdSI);  /* set edit inpoint */
  547.     mc_convert(MC_NTSC_FRAME, MC_NTSC_TC, fcntSI + MINENDPOINT, tcTMP);
  548.     setVCmdStr(cmdSO, strSO, tcSO, tcTMP);
  549.     response = vlan_SendCmd(cmdSO);  /* set edit outpoint */
  550.     setVCmdStr(cmdPR, strPR, tcPR, tcPR);
  551.     response = vlan_SendCmd(cmdPR);  /* set preroll time */
  552.     setVCmdStr(cmdSC, strSC, tcSC, tcPR);
  553.     response = vlan_SendCmd(cmdSC);  /* set coincidence trigger time */
  554.     response = vlan_SendCmd("RV");   /* start review of edit sequence */
  555.     if (response != NULL && response[0] != '\0')
  556.         fprintf(stdout, "%s\n", response);
  557. }
  558.  
  559.  
  560. void
  561. setNewVlanCaptSeq(int count)
  562. {
  563.     fcntSI += captCount;
  564.     mc_convert(MC_NTSC_FRAME, MC_NTSC_TC, fcntSI, tcTMP);
  565.     setVCmdStr(cmdSI, strSI, tcSI, tcTMP);
  566.     response = vlan_SendCmd(cmdSI);
  567.     mc_convert(MC_NTSC_FRAME, MC_NTSC_TC, fcntSI + MINENDPOINT, tcTMP);
  568.     setVCmdStr(cmdSO, strSO, tcSO, tcTMP);
  569.     response = vlan_SendCmd(cmdSO);
  570.     response = vlan_SendCmd("RV");
  571. }
  572.  
  573.  
  574.  
  575. main(int argc, char **argv)
  576. {
  577.     div_t tmp;
  578.     
  579.     _progName = argv[0];
  580.  
  581.     setVCmdStr(cmdPR, strPR, tcPR, "00:00:05:00"); /* default preroll time of 5 sec. */
  582.     
  583.     parseOptions(argc, argv);
  584.     
  585.     if (!inpoint) {
  586.     usage();
  587.     exit(0);
  588.     }
  589.     
  590.     /* Ensure that writeFrame is enabled if -d option specified */
  591.     if (displayFrame && !writeFrame) 
  592.     {
  593.     writeFrame = 1;
  594.     forcedWriteFrame = 1;
  595.     }
  596.  
  597.  
  598.     if (writeFrame)
  599.     {
  600.     if (outfilename[0] == '\0')
  601.         strcpy(outfilename, GRABFILE);
  602.     }
  603.  
  604.     /* compute total number of frames to grab based on inpoint and outpoint */
  605.     mc_convert(MC_NTSC_TC, MC_NTSC_FRAME, tcSO, &fcntSO);
  606.     mc_convert(MC_NTSC_TC, MC_NTSC_FRAME, tcSI, &fcntSI);
  607.     fcntSI += offset;
  608.     fcntSO += offset;
  609.     totalFrames = fcntSO - fcntSI + 1;
  610.     if (totalFrames <= 0) {
  611.       printf("end frame must be greater than start frame\n");
  612.       exit(-1);
  613.     }
  614.     
  615.     if (captCount == 0) {
  616.       if (totalFrames < MAXFGRAB)
  617.         captCount = totalFrames;
  618.       else
  619.     captCount = MAXFGRAB;
  620.     }
  621.  
  622.     initVideo();
  623.         
  624.     tmp = div(totalFrames, captCount);
  625.     totalTriggers = tmp.quot;
  626.     remFrames = tmp.rem;
  627.     printf("totalFrames = %d totalTriggers %d\n", totalFrames, 
  628.         tmp.rem ? totalTriggers + 1 : totalTriggers);
  629.     
  630.     /*
  631.      * Fill the transfer descriptor for a discrete transfer of captCount
  632.      * frames based on a trigger event.
  633.      */
  634.  
  635.     xferDesc.mode = VL_TRANSFER_MODE_DISCRETE;
  636.     xferDesc.count = captCount;
  637.     xferDesc.delay = 0;
  638.     xferDesc.trigger = VLDeviceEvent;
  639.  
  640.     /* Begin the data transfer */
  641.     vlBeginTransfer(svr, path, 1, &xferDesc);
  642.  
  643.     if (vlan_InitPort("/dev/ttyd2") != 0) {
  644.         sprintf(buf, "Can't open %s\n", vlan_port);
  645.         vlan_perror(buf);
  646.         exit(1);
  647.     }
  648.     
  649.     printf("Sending vlan edit setup sequence\n");
  650.     
  651.     initVlanEditSeq();
  652.  
  653.     /* Loop until all requested frames are grabbed */
  654.     vlMainLoop();
  655.  }
  656.  
  657. /* 
  658.  * Handle video library events 
  659.  * (only transfer complete and transfer failed events in this example) 
  660.  */
  661. void
  662. ProcessEvent(VLServer svr, VLEvent *ev, void *data)
  663. {
  664.     VLInfoPtr info;
  665.     char *dataPtr;
  666.     DMediaInfo *dmInfo;
  667.     int iFrame, msec;
  668.     char tcstr[256];
  669.     int elapsedTime;
  670.     int elapsedFrames;
  671.     static numTrigs = 0;
  672.     static int framesGrabbed = 0;
  673.     static int frames = 0;
  674.     
  675.     switch (ev->reason)
  676.     {
  677.     case VLTransferComplete:
  678.         /* Get the number and location of frames captured */
  679.  
  680.         while ((info = vlGetNextValid(svr, buffer)) == NULL);
  681.         dmInfo = vlGetDMediaInfo(svr, buffer, info);
  682.         if (verbose)
  683.           printf("field sequence # = %d\n", dmInfo->sequence);
  684.         
  685.         /* Get a pointer to the frame(s) */
  686.         dataPtr = vlGetActiveRegion(svr, buffer, info);
  687.         
  688.         frames++;
  689.         framesGrabbed++;
  690.         
  691.         if (decodeTC) {
  692.         }
  693.             
  694.         /* Set the filename if user requested write to disk */
  695.         if (writeFrame) {
  696.              sprintf(iname,"%s-%05d", outfilename, framesGrabbed);
  697.              if (!rawMode)
  698.              strcat(iname, ".rgb");
  699.              else {
  700.              strcat(iname, ".");
  701.              strcat(iname, get_packing());
  702.              }
  703.         }
  704.         
  705.         /* Write the frame(s) to memory (and to disk if requested) */
  706.         DumpImage(dataPtr, xsize, xsetsize, ysize, ysetsize, frameSize);
  707.  
  708.         if (writeFrame && !forcedWriteFrame) 
  709.           fprintf(stderr,"%s: saved image to file %s\n", _progName, iname);
  710.             
  711.         /* Write to display if requested */
  712.         if (displayFrame && !rawMode) {
  713.             char cmd[100];
  714.         
  715.             sprintf(cmd, "ipaste %s ", iname);
  716.             system(cmd);
  717.             if (forcedWriteFrame)
  718.                unlink(iname);
  719.             }
  720.             
  721.         /* Finished with frame, unlock the buffer */
  722.         vlPutFree(svr, buffer);
  723.  
  724.         if (frames < captCount)
  725.           break;
  726.          
  727.         ++numTrigs;
  728.        
  729.         if (verbose)
  730.           printf(">> trigger: %d of %d\n", numTrigs, totalTriggers);
  731.           
  732.         frames = 0;
  733.         
  734.         printf("grabbed %d frames\n", captCount);
  735.         vlEndTransfer(svr, path);
  736.       
  737.         if (numTrigs < totalTriggers) {
  738.            xferDesc.count = captCount;
  739.            vlBeginTransfer(svr, path, 1, &xferDesc);
  740.         
  741.            setNewVlanCaptSeq(captCount);
  742.          }
  743.         else if (remFrames) {
  744.            xferDesc.count = captCount;
  745.            vlBeginTransfer(svr, path, 1, &xferDesc);
  746.         
  747.            setNewVlanCaptSeq(remFrames);
  748.            captCount = remFrames;
  749.            remFrames = 0;
  750.         }
  751.             else   
  752.         {
  753.           printf("done grabbing frames.\n");
  754.           docleanup();
  755.         }
  756.     break;
  757.     
  758.     case VLTransferFailed:    
  759.         fprintf(stderr,"%s: Transfer failed.\n",_progName);
  760.         docleanup();
  761.     break;
  762.     
  763.     default:
  764.       printf("a non-transfer event happened\n");
  765.     break;
  766.     }
  767. }
  768.  
  769.  
  770.  
  771. int reportPerf(int reset)
  772. {
  773.    static int nframes = 0;
  774.    static struct timeval starttime, endtime;
  775.    double perf;
  776.    long lperf;
  777.  
  778.    if (reset)
  779.      gettimeofday(&starttime);
  780.    else {
  781.      gettimeofday(&endtime);
  782.      perf =  (((double)((endtime.tv_sec - starttime.tv_sec) * 1000000
  783.                      + (endtime.tv_usec - starttime.tv_usec))) / 1000000.0);
  784.      lperf =  ((((endtime.tv_sec - starttime.tv_sec) * 1000000
  785.                      + (endtime.tv_usec - starttime.tv_usec))));
  786.      starttime = endtime;
  787.      fprintf(stderr, "%6.3f seconds elapsed\n", perf);
  788.      return(lperf);
  789.    }
  790. }
  791.  
  792.  
  793. /*
  794.  * Do general cleanup before exiting. All of our resources should 
  795.  * be freed.
  796.  */
  797. void
  798. docleanup()
  799. {
  800.     vlEndTransfer(svr, path);
  801.     vlDeregisterBuffer(svr, path, drn, buffer);
  802.     vlDestroyBuffer(svr, buffer);
  803.     vlDestroyPath(svr, path);
  804.     vlCloseVideo(svr);
  805.     exit(0);
  806. }
  807.  
  808. char * 
  809. get_packing(void)
  810. {
  811.     VLControlValue val;
  812.     char *packing;
  813.     
  814.     if (vlGetControl(svr, path, drn, VL_PACKING, &val) < 0)
  815.     vlPerror("Getting VL_PACKING");
  816.     
  817.     switch (val.intVal) 
  818.     {
  819.     case VL_PACKING_RGB_8:    
  820.         packing = "rgb";
  821.     break;
  822.     
  823.         case VL_PACKING_RGBA_8:   
  824.         packing = "rgba";
  825.     break;
  826.     
  827.     case VL_PACKING_RBG_323:   
  828.         packing = "rgb323";
  829.     break;
  830.     
  831.     case VL_PACKING_RGB_332_P:    
  832.         packing = "rgb332p";
  833.     break;
  834.     
  835.     case VL_PACKING_Y_8_P: 
  836.         packing = "yuvluma";
  837.     break;
  838.     
  839.     case VL_PACKING_VUY_411_SV:
  840.         packing = "yuv411";
  841.     break;
  842.     
  843.     case VL_PACKING_YVYU_422_8:
  844.         packing = "yuv422";
  845.     break;
  846.     
  847.     case VL_PACKING_RGB_332:               
  848.         packing = "rgb332";
  849.     break;
  850.  
  851.     case VL_PACKING_BGR_332:           
  852.         packing = "bgr332";
  853.     break;
  854.  
  855.     case VL_PACKING_RGB_332_IP:
  856.         packing = "rgb332ip";
  857.     break;
  858.  
  859.     case VL_PACKING_BGR_332_P:
  860.         packing = "bgr332p";
  861.     break;
  862.  
  863.     case VL_PACKING_BGR_332_IP:
  864.         packing = "bgr332ip";
  865.     break;
  866.  
  867.     case VL_PACKING_RGB_565:
  868.         packing = "rgb565";
  869.     break;
  870.  
  871.     case VL_PACKING_RGB_565_P:
  872.         packing = "rgb565P";
  873.     break;
  874.  
  875.     case VL_PACKING_RGB_8_P:
  876.         packing = "rgb8p";
  877.     break;
  878.  
  879.     case VL_PACKING_RGB_10:    
  880.         packing = "rgb10";
  881.     break;
  882.  
  883.     case VL_PACKING_Y_8_IP:
  884.         packing = "yuvlumaip";
  885.     break;
  886.  
  887.     case VL_PACKING_YUV_444_8:
  888.         packing = "yuv44";
  889.     break;
  890.  
  891.     case VL_PACKING_YUVA_4444_8:
  892.         packing = "yuva444";
  893.     break;
  894.  
  895.     case VL_PACKING_YUV_444_10:    
  896.         packing = "yuv44410";
  897.     break;
  898.  
  899.     default:
  900.         packing = "???";
  901.     break;
  902.     }
  903.     return(packing);
  904. }
  905.  
  906.  
  907.